# coding:utf-8
from scapy.all import *
from requests import *
import time
# conf.iface = 'Intel(R) Dual Band Wireless-AC 8260'
start_time = time.time()

dga_list = []
dga_data = open('dga.txt', 'r')
dga_data = (dga_data.readlines())[18:]
for dga in dga_data:
    dga_list.append(dga.split('\t')[1])
data = set(dga_list)
end_time = time.time()
print('读取dga.txt 耗时 %0.2f s' % (end_time - start_time))


# 时间戳转换函数
def TimeStamp2Time(time_stamp):
    time_tmp = time.localtime(time_stamp)  # time.localtime()格式化时间戳为本地时间
    format_time = time.strftime("%Y-%m-%d %H:%M:%S", time_tmp)  # 将本地时间格式化为字符串
    return format_time


def get_local_ip():
    hostname = socket.gethostname()
    local_ips = socket.gethostbyname_ex(hostname)[-1]  # 获取本机内网ip
    return local_ips


def body_transfer(body):
    str_body = body.decode()
    body_ls = str_body.split("&")
    for item in body_ls:
        key_, value_ = item.split("=")
        print("   %s: %s" % (key_, value_))


# Capture and Filter DGA
def capture(packet):
    try:
        local_ips = get_local_ip()
        # print(packet.show())  # 内置的show()函数打印数据包内容
        # for item in packet:
        #     print('time：', item.time)
        #     print('fields：', item.fields)
        #     print('overload_fields：', item.overload_fields)
        #     print('fields：', item.fields)
        #     print('payload：', item.payload)
        #     print('wirelen：', item.wirelen)
        # print('---------------------------------------')
        if packet:
            for item in packet:
                ip_packet = item['IP']
                dns_packet = item['DNS']
                print(('src:%s----->dst:%s (len=%d ttl=%d time=%s)' % (
                    ip_packet.src + "(本机)" if ip_packet.src in local_ips else ip_packet.src, ip_packet.dst, ip_packet.len,
                    ip_packet.ttl, TimeStamp2Time(item.time))))
                sport = item['UDP'].sport
                dport = item['UDP'].dport
                qr = str(item['DNS'].qr)
                rcode = str(item['DNS'].rcode)

                if '0' in qr:
                    qr = 'Query'
                    qname = dns_packet.qd.qname
                    if type(qname) == bytes:
                        qname = (qname.decode('utf-8'))[:-1]
                    if qname in data:
                        print("[*] Found DGA Request:-->", ip_packet.src, sport, qr, qname)

                elif '1' in qr:
                    if '0' in rcode:
                        for j in range(10):
                            try:
                                qr = 'Response'
                                rrname = item[j]['DNS'].an[j].rrname
                                rdata = item[j]['DNS'].an[j].rdata
                                if type(rrname) == bytes:
                                    rrname = (rrname.decode('utf-8'))[:-1]
                                    if type(rdata) == bytes:
                                        rdata = (rdata.decode('utf-8'))[:-1]
                                if rrname in data:
                                    print("[*] Found DGA Response:-->", ip_packet.src, ip_packet.dst, qr, rrname, rdata,
                                          "\n")
                            except Exception:
                                pass
    except:
        pass


# update dga_file
def dga_file_update():
    url = 'http://data.netlab.360.com/feeds/dga/dga.txt'
    dga_file = get(url)
    with open('./dga.txt', 'w') as f:
        f.write(dga_file.text)
        print('Download DGAFile Finished')


if __name__ == '__main__':
    print(get_local_ip())
    sniff(prn=capture, filter='udp port 53')
    while True:
        dga_file_update()
        time.sleep(86400)
